function [Z_new,X_id] = residualizer(Z,X,market,style)

if strcmp(style,'semiparametric')
    
    beta  = X\Z;
    Z_new = Z-X*beta;
    
elseif strcmp(style,'nonparametric')

% sort markets into 10 different columns according to their market size

cell_source   = cell(710,10);
pos_source    = zeros(1,10);

for m = 1:max(market)
    num_prod = length(Z(market==m))-28; % min-max market size: 29-38
    pos_source(num_prod) = pos_source(num_prod)+1;
    cell_source{pos_source(num_prod),num_prod} = {m,X(market==m,:),Z(market==m)};
end


% within each column, group markets that are identical in X

equal_markets = cell(710,10);
market_type   = cell(710,10);
Z_in_markets  = cell(710,10);

for i = 1:10
    
    cell_col = cell_source(:,i);
    cell_col = cell_col(~cellfun('isempty',cell_col));
    pos_markets   = 1;
    
    for k = 1:length(cell_col)

        for n = 1:pos_markets
            
            if isempty(equal_markets{n,i})
                equal_markets{n,i} = cell_col{k,1}{1,1};
                market_type{n,i}   = cell_col{k,1}{1,2};
                Z_in_markets{n,i}  = cell_col{k,1}{1,3};
                pos_markets        = pos_markets+1;
                break
            elseif cell_col{k,1}{1,2} == market_type{n,i}
                equal_markets{n,i} = [equal_markets{n,i},cell_col{k,1}{1,1}];
                Z_in_markets{n,i}  = [Z_in_markets{n,i},cell_col{k,1}{1,3}];
                break
            else
            end
        end
                
    end
end


% remove empty cells and stack all market groups

equal_markets = equal_markets(~cellfun('isempty',equal_markets));
Z_in_markets  = Z_in_markets(~cellfun('isempty',Z_in_markets));


% construct new instrument Z_new = Z - E[Z|X=x]

Z_new = nan(size(Z));
X_id  = nan(size(Z));

for m = 1:max(market)
    for n = 1:length(equal_markets)
        if ismember(m,equal_markets{n})
            Z_new(m==market) = Z(m==market)-mean(Z_in_markets{n},2);
            X_id(m==market)  = n;
            break
        end
    end
end

end


end
